/************************************************************************/
/* global vars                                                                     */
/************************************************************************/
var conf = {
    debug: false,
    showDebugInfo: false,
    showSystemMessage: false,
    fontSize: "12px",
    /* see http://msdn.microsoft.com/en-us/library/aa974179.aspx#sizing */
    maxGadgetHeight: 400, 
    minGadgetHeight: 100,
    colorMessageUnknown: "#ff0000",
    colorMessageSending: "#999999",
    colorMessageSent: "#ffffff",
    colorMessageReceived: "#999999",
    colorMessageRead: "#ffffff",
    hideOfflineUser: false,
    apiTimeout: 1000,
	maxMessage: 300,
	lastPane: 0
};

var flgAutoScroll = true;
var flgDrag = false;
var debugMessageCount = 0;
/** Main Pane */
var MP;

/** Friend List Window */
var FLWnd;

if(Skype) Skype.Timeout = conf.apiTimeout;

/************************************************************************/
/* Skype Event Handlers                            �?                                          */
/************************************************************************/
function G_RegistEventHandler() {
    eval('function Skype::AttachmentStatus(Status){G_OnAttachmentStatus(Status);};');
    eval('function Skype::OnlineStatus(user, status){if(MP)MP.friendListPane.changeOnlineStatus(user, status);};');
    eval('function Skype::MessageStatus(pMessage, sStatus){if(MP)MP.chatMessagePane.changeMessageStatus(pMessage, sStatus);};');
/*    
        function Skype::Command(pCommand){};
        function Skype::Reply(pCommand){};
        function Skype::Error(pCommand, sNumber, sDescription){};
        function Skype::AttachmentStatus(Status){
            G_OnAttachmentStatus(Status);
        };
        function Skype::ConnectionStatus(Status){};
        function Skype::UserStatus(Status){};
        function Skype::OnlineStatus(user, status){
            if(MP)MP.friendListPane.changeOnlineStatus(user, status);
        };
        function Skype::CallStatus(pCall, sStatus){};
        function Skype::CallHistory(){};
        function Skype::Mute(Mute){};
        function Skype::MessageStatus(pMessage, sStatus){
            if(MP)MP.chatMessagePane.changeMessageStatus(pMessage, sStatus);
        };
        function Skype::MessageHistory(Username){};
        function Skype::AutoAway(Automatic){};
        function Skype::CallDtmfReceived(pCall, sCode){};
        function Skype::VoicemailStatus(pMail, sStatus){};
        function Skype::ApplicationConnecting(pApp, spUsers){};
        function Skype::ApplicationStreams(pApp, spStreams){};
        function Skype::ApplicationDatagram(pApp, spStream, sText){};
        function Skype::ApplicationSending(pApp, spStreams){};
        function Skype::ApplicationReceiving(pApp, spStreams){};
        function Skype::ContactsFocused(Username){};
        function Skype::GroupVisible(pGroup, sVisible){};
        function Skype::GroupExpanded(pGroup, sExpanded){};
        function Skype::GroupUsers(pGroup, spUsers){};
        function Skype::GroupDeleted(GroupId){};
        function Skype::UserMood(pUser, sMoodText){};
        function Skype::SmsMessageStatusChanged(pMessage, sStatus){};      
        function Skype::SmsTargetStatusChanged(pTarget, sStatus){};      
        function Skype::CallInputStatusChanged(pCall, sStatus){};      
        function Skype::AsyncSearchUsersFinished(Cookie, spUsers){};
        function Skype::CallSeenStatusChanged(pCall, Status){};
        function Skype::PluginEventClicked(pEvent){};
        function Skype::PluginMenuItemClicked(pMenuItem, spUsers, sPluginContext, sContextId){};
        function Skype::WallpaperChanged(Path){};
        function Skype::FileTransferStatusChanged(pTransfer, sStatus){};      
        function Skype::CallTransferStatusChanged(pCall, sStatus){};
        function Skype::ChatMembersChanged(pChat, spMembers){};
        function Skype::ChatMemberRoleChanged(pMember, sRole){};
        function Skype::CallVideoStatusChanged(pCall, sStatus){};
        function Skype::CallVideoSendStatusChanged(pCall, sStatus){};
        function Skype::CallVideoReceiveStatusChanged(pCall, sStatus){};
        function Skype::SilentModeStatusChanged(Silent){};
        function Skype::UILanguageChanged(Code){};
        function Skype::UserAuthorizationRequestReceived(pUser){};
*/
}

/************************************************************************/
/* Enums                                                                     */
/************************************************************************/
TAttachmentStatus =
{
     apiAttachUnknown : -1,
     apiAttachSuccess : 0,
     apiAttachPendingAuthorization : 1,
     apiAttachRefused : 2,
     apiAttachNotAvailable : 3,
     apiAttachAvailable : 4
};

TConnectionStatus =
{
     conUnknown : -1,
     conOffline : 0,
     conConnecting : 1,
     conPausing : 2,
     conOnline : 3
};

TUserStatus = 
{
     cusUnknown : -1,
     cusOffline : 0,
     cusOnline : 1,
     cusAway : 2,
     cusNotAvailable : 3,
     cusDoNotDisturb : 4,
     cusInvisible : 5,
     cusLoggedOut : 6,
     cusSkypeMe : 7
};

TCallFailureReason = 
{
     cfrUnknown : -1,
     cfrMiscError : 0,
     cfrUserDoesNotExist: 1,
     cfrUserIsOffline : 2,
     cfrNoProxyFound : 3,
     cfrSessionTerminated: 4,
     cfrNoCommonCodec : 5,
     cfrSoundIOError : 6,
     cfrRemoteDeviceError : 7,
     cfrBlockedByRecipient : 8,
     cfrRecipientNotFriend : 9,
     cfrNotAuthorizedByRecipient : 10,
     cfrSoundRecordingError : 11
};

TCallStatus =
{
     clsUnknown : -1,
     clsUnplaced : 0,
     clsRouting : 1,
     clsEarlyMedia : 2,
     clsFailed : 3,
     clsRinging : 4,
     clsInProgress : 5,
     clsOnHold : 6,
     clsFinished : 7,
     clsMissed : 8,
     clsRefused : 9,
     clsBusy : 10,
     clsCancelled : 11,
     clsLocalHold : 12,
     clsRemoteHold : 13,
     clsVoicemailBufferingGreeting : 14,
     clsVoicemailPlayingGreeting : 15,
     clsVoicemailRecording : 16,
     clsVoicemailUploading : 17,
     clsVoicemailSent : 18,
     clsVoicemailCancelled : 19,
     clsVoicemailFailed : 20,
     clsTransferring: 21,
     clsTransferred: 22
};

TCallType =
{
     cltUnknown : -1,
     cltIncomingPSTN : 0,
     cltOutgoingPSTN : 1,
     cltIncomingP2P : 2,
     cltOutgoingP2P : 3
};

TCallHistory =
{
     chsAllCalls : 0,
     chsMissedCalls : 1,
     chsIncomingCalls : 2,
     chsOutgoingCalls : 3
};

TCallVideoStatus =
{
     cvsUnknown : -1,
     cvsNone : 0,
     cvsSendEnabled : 1,
     cvsReceiveEnabled : 2,
     cvsBothEnabled : 3
};

TCallVideoSendStatus =
{
     vssUnknown : -1,
     vssNotAvailable : 0,
     vssAvailable : 1,
     vssStarting : 2,
     vssRejected : 3,
     vssRunning : 4,
     vssStopping : 5,
     vssPaused : 6
};

TCallIoDeviceType =
{
     callIoDeviceTypeUnknown : -1,
     callIoDeviceTypeSoundcard: 0,
     callIoDeviceTypePort : 1,
     callIoDeviceTypeFile : 2
};

TChatMessageType =
{
     cmeUnknown : -1,
     cmeCreatedChatWith : 0,
     cmeSawMembers: 1,     
     cmeAddedMembers : 2,
     cmeSetTopic : 3,
     cmeSaid : 4,
     cmeLeft : 5,
     cmeEmoted : 6,
     cmePostedContacts : 7,
     cmeGapInChat : 8,
     cmeSetRole : 9,
     cmeKicked : 10,
     cmeSetOptions : 11,
     cmeKickBanned : 12,
     cmeJoinedAsApplicant : 13,
     cmeSetPicture : 14,
     cmeSetGuidelines : 15
};

TChatMessageStatus =
{
     cmsUnknown : -1,
     cmsSending : 0,
     cmsSent : 1,
     cmsReceived : 2,
     cmsRead : 3
};

TChatMemberRole =
{
     chatMemberRoleUnknown : -1,
     chatMemberRoleCreator : 0,
     chatMemberRoleMaster : 1,
     chatMemberRoleHelper : 2,
     chatMemberRoleUser : 3,
     chatMemberRoleListener : 4,
     chatMemberRoleApplicant : 5
};

TUserSex =
{
     usexUnknown : -1,
     usexMale : 0,
     usexFemale : 1
};

TBuddyStatus =
{
     budUnknown : -1,
     budNeverBeenFriend : 0,
     budDeletedFriend : 1,
     budPendingAuthorization : 2,
     budFriend : 3
};

TOnlineStatus =
{
     olsUnknown : -1,
     olsOffline : 0,
     olsOnline : 1,
     olsAway : 2,
     olsNotAvailable : 3,
     olsDoNotDisturb : 4,
     olsSkypeOut : 5,
     olsSkypeMe : 6     
};

TChatLeaveReason =
{
     leaUnknown : -1,
     leaUserNotFound : 0,
     leaUserIncapable : 1,
     leaAdderNotFriend : 2,
     leaAddedNotAuthorized : 3,
     leaAddDeclined : 4,
     leaUnsubscribe : 5
};

TChatStatus =
{
     chsUnknown : -1,
     chsLegacyDialog : 0,
     chsDialog : 1,
     chsMultiNeedAccept : 2,
     chsMultiSubscribed : 3,
     chsUnsubscribed: 4
};

TChatType =
{
     chatTypeUnknown : -1,
     chatTypeDialog : 0,
     chatTypeLegacyDialog : 1,
     chatTypeLegacyUnsubscribed : 2,
     chatTypeMultiChat : 3,
     chatTypeSharedGroup : 4
};

TChatMyStatus =
{
     chatStatusUnknown : -1,
     chatStatusConnecting : 0,
     chatStatusWaitingRemoteAccept : 1,
     chatStatusAcceptRequired : 2,
     chatStatusPasswordRequired : 3,
     chatStatusSubscribed : 4,
     chatStatusUnsubscribed : 5,
     chatStatusDisbanded : 6,
     chatStatusQueuedBecauseChatIsFull : 7,
     chatStatusApplicationDenied : 8,
     chatStatusKicked : 9,
     chatStatusBanned : 10,
     chatStatusRetryConnecting : 11
};

TChatOptions =
{
     chatOptionJoiningEnabled : 1,
     chatOptionJoinersBecomeApplicants : 2,
     chatOptionJoinersBecomeListeners : 4,
     chatOptionHistoryDisclosed : 8,
     chatOptionUsersAreListeners : 16,
     chatOptionTopicAndPictureLockedForUsers : 32
};

TVoicemailType =
{
     vmtUnknown : -1,
     vmtIncoming : 0,
     vmtDefaultGreeting : 1,
     vmtCustomGreeting : 2,
     vmtOutgoing : 3
};

TVoicemailStatus =
{
     vmsUnknown : -1,
     vmsNotDownloaded : 0, 
     vmsDownloading : 1, 
     vmsUnplayed : 2, 
     vmsBuffering : 3, 
     vmsPlaying : 4, 
     vmsPlayed : 5, 
     vmsBlank : 6, 
     vmsRecording : 7, 
     vmsRecorded : 8, 
     vmsUploading : 9, 
     vmsUploaded : 10, 
     vmsDeleting : 11, 
     vmsFailed : 12
};

TVoicemailFailureReason =
{
     vmrUnknown : -1,
     vmrNoError : 0, 
     vmrMiscError : 1, 
     vmrConnectError : 2, 
     vmrNoPrivilege : 3, 
     vmrNoVoicemail : 4, 
     vmrFileReadError : 5, 
     vmrFileWriteError : 6, 
     vmrRecordingError : 7, 
     vmrPlaybackError : 8
};

TGroupType =
{
     grpUnknown : -1,
     grpCustomGroup : 0, 
     grpAllUsers : 1,
     grpAllFriends : 2,
     grpSkypeFriends : 3,
     grpSkypeOutFriends : 4,
     grpOnlineFriends : 5,
     grpPendingAuthorizationFriends : 6,
     grpRecentlyContactedUsers : 7,
     grpUsersWaitingMyAuthorization : 8,
     grpUsersAuthorizedByMe : 9,
     grpUsersBlockedByMe : 10,
     grpUngroupedFriends : 11,
     grpSharedGroup : 12,
     grpProposedSharedGroup : 13
};

TCallChannelType =
{
     cctUnknown: -1,
     cctDatagram: 0,
     cctReliable : 1
};

TApiSecurityContext =
{
     apiContextUnknown : 0x0000,
     apiContextVoice : 0x0001,
     apiContextMessaging : 0x0002,
     apiContextAccount : 0x0004,
     apiContextContacts : 0x0008     
};

TSmsMessageType =
{
     smsMessageTypeUnknown : -1,
     smsMessageTypeIncoming : 0,
     smsMessageTypeOutgoing : 1,
     smsMessageTypeCCRequest : 2,
     smsMessageTypeCCSubmit : 3     
};

TSmsMessageStatus =
{
     smsMessageStatusUnknown : -1,
     smsMessageStatusReceived : 0,
     smsMessageStatusRead : 1,
     smsMessageStatusComposing : 2,
     smsMessageStatusSendingToServer : 3,
     smsMessageStatusSentToServer : 4,
     smsMessageStatusDelivered : 5,
     smsMessageStatusSomeTargetsFailed : 6,
     smsMessageStatusFailed : 7
};

TSmsFailureReason =
{
     smsFailureReasonUnknown : -1,
     smsFailureReasonMiscError : 0,
     smsFailureReasonServerConnectFailed : 1,
     smsFailureReasonNoSmsCapability : 2,
     smsFailureReasonInsufficientFunds : 3,
     smsFailureReasonInvalidConfirmationCode : 4,
     smsFailureReasonUserBlocked : 5,
     smsFailureReasonIPBlocked : 6,
     smsFailureReasonNodeBlocked : 7
};

TSmsTargetStatus =
{
     smsTargetStatusUnknown : -1,   
     smsTargetStatusUndefined : 0,
     smsTargetStatusAnalyzing : 1,
     smsTargetStatusAcceptable : 2,
     smsTargetStatusNotRoutable : 3,
     smsTargetStatusDeliveryPending : 4,
     smsTargetStatusDeliverySuccessful : 5,
     smsTargetStatusDeliveryFailed : 6
};

TPluginContext =
{
     pluginContextUnknown : -1, 
     pluginContextChat : 0,  
     pluginContextCall : 1,  
     pluginContextContact : 2,  
     pluginContextMyself : 3, 
     pluginContextTools : 4
};

TPluginContactType =
{
     pluginContactTypeUnknown : -1,  
     pluginContactTypeAll : 0,  
     pluginContactTypeSkype : 1, 
     pluginContactTypeSkypeOut: 2
};

TFileTransferType =
{
     fileTransferTypeIncoming : 0,   
     fileTransferTypeOutgoing : 1
};

TFileTransferStatus =
{
     fileTransferStatusNew : 0,   
     fileTransferStatusConnecting : 1, 
     fileTransferStatusWaitingForAccept : 2,
     fileTransferStatusTransferring : 3,
     fileTransferStatusTransferringOverRelay : 4,
     fileTransferStatusPaused : 5,
     fileTransferStatusRemotelyPaused : 6,
     fileTransferStatusCancelled : 7,
     fileTransferStatusCompleted : 8,
     fileTransferStatusFailed : 9
};

TFileTransferFailureReason =
{
     fileTransferFailureReasonSenderNotAuthorized: 1, 
     fileTransferFailureReasonRemotelyCancelled: 2,  
     fileTransferFailureReasonFailedRead : 3,   
     fileTransferFailureReasonFailedRemoteRead : 4,   
     fileTransferFailureReasonFailedWrite : 5, 
     fileTransferFailureReasonFailedRemoteWrite : 6, 
     fileTransferFailureReasonRemoteDoesNotSupportFT : 7,   
     fileTransferFailureReasonRemoteOfflineTooLong : 8
};

/************************************************************************/
/* Gadget Function                                                                     */
/************************************************************************/
function G_LoadSettings() {
    G_Debug("G_LoadSettings()");
    var settings = System.Gadget.Settings;
    for(var name in conf) {
        var settingVal = settings.read(name);
        if(settingVal == null || settingVal.length == 0) {
            G_Debug("write:" + name + "=" +  conf[name]);
            settings.write(name, conf[name]);
        } else {
            G_Debug("load:" + name + "=" + settings.read(name));
            conf[name] = settings.read(name);
        }
    }
    if(MP) {
        MP.refresh();
    }
}

function G_OnResize(e) {
    var resizeBarOffset = $("#resize-grab-pane").offset();
    
	var newHeight = 
		e.pageY 
		+ $("body").height()
        - (resizeBarOffset.top 
                + $("#resize-grab-pane").height() / 2
                - 1
          );
	newHeight = Math.min(conf.maxGadgetHeight, newHeight);
	newHeight = Math.max(conf.minGadgetHeight, newHeight);
    $("body").height(newHeight);
    
    $("#bg-body").height(
        $("body").height()
        - $("#bg-header").height()
        - $("#bg-footer").height()
    );
    
    
    $("#main-pane").height(
        $("body").height() 
        - $("#main-pane").offset().top 
        - $("#bg-footer").height()
        - 4
    );
    
}

function G_OnSettingsClosed(e) {
    if (e.closeAction == e.Action.commit)
    {
		G_LoadSettings();
    }
}

function G_OnAttachmentStatus(status) {
    if(MP) MP.hideError();
    switch(status) {
    case  TAttachmentStatus.apiAttachUnknown :
        G_Error(MessageResource.ERROR.API_NOT_ATTACHED);
        G_SystemMessage(MessageResource.SYSTEM.API_ATTACH_UNKNOWN);
        break;
    case TAttachmentStatus.apiAttachSuccess:
        G_SystemMessage(MessageResource.SYSTEM.API_ATTACH_SUCCESS);
        break;
    case TAttachmentStatus.apiAttachPendingAuthorization :
        G_SystemMessage(MessageResource.SYSTEM.API_ATTACH_PENDING_AUTHORIZATION);
        break;
    case TAttachmentStatus.apiAttachRefused:
        G_Error(MessageResource.ERROR.API_NOT_ATTACHED);
        G_SystemMessage(MessageResource.SYSTEM.API_ATTACH_REFUSED);
        break;
    case TAttachmentStatus.apiAttachNotAvailable:
        G_Error(MessageResource.ERROR.API_NOT_ATTACHED);
        G_SystemMessage(MessageResource.SYSTEM.API_ATTACH_NOT_AVAILABLE);
        break;
    case TAttachmentStatus.apiAttachAvailable:
        G_SystemMessage(MessageResource.SYSTEM.API_ATTACH_AVAILABLE);
        G_AttachToSkype();
        break;
    default:
        // Do Nothing.
    }
}

function G_AttachToSkype() {
    try {
        if(Skype) {
            //if(Skype.AttachmentStatus == TAttachmentStatus.apiAttachAvailable) {
                G_SystemMessage(MessageResource.SYSTEM.ATTACH_TO_SKYPE);
                Skype.Timeout = conf.apiTimeout;
                Skype.Attach(5,false);
            //}
        } 
    } catch(e) {
        G_Error(MessageResource.ERROR.API_OPERATION_TIMEOUT);
    }
}

function G_Debug(msg) {
    System.Debug.outputString(msg);
    if(MP) 
    MP.chatMessagePane.appendDebugMessage(msg);
}

function G_SystemMessage(msg) {
    if(MP)
    MP.chatMessagePane.appendSystemMessage(msg);
}

function G_Error(msg) {
    if(MP) MP.error(msg);
}

function G_InstallCOM() {
    
    //$("body").append("<iframe src='lib/regcom.bat'></iframe>");
   	window.open(System.Gadget.path + '/skype4com/install.html','_blank');
	//location.href='lib/regcom.bat';
    setTimeout(G_CheckCOM, 1000);
    
}
function G_CheckCOM() {
    try {
        Skype = new ActiveXObject("Skype4COM.Skype");
        var dummy = Skype.AttachmentStatus;
        G_RegistEventHandler();
        G_AttachToSkype();
        MP.hideError();
    } catch(e) {
        setTimeout(G_CheckCOM, 1000); 
    }
}

/************************************************************************/
/* Util                                                                     */
/************************************************************************/
(function () {
    var Util = window.Util = function () {
        return new Util.fn.init();
    };
    Util.fn = {
        init : function () {
        },
        htmlEncode : function(str) {
            str = str.replace(/&/g,"&amp;") ;
            str = str.replace(/"/g,"&quot;") ;
            str = str.replace(/'/g,"&#039;") ;
            str = str.replace(/</g,"&lt;") ;
            str = str.replace(/>/g,"&gt;") ;
            return str ;
                
        },
        jquerySelectorEscape : function(str) {
            
            //Note: if you wish to use any of the meta-characters described above as a literal part of a name, you must escape the character with two backslashes (\). For example:
            //#foo\\:bar
            //#foo\\[bar\\]
            //#foo\\.bar
            str = str.replace(".", "\\.");
            str = str.replace("[", "\\[");
            str = str.replace(":", "\\:");
            return str;
        }
    }
    Util.fn.init.prototype = Util.fn;
}
)();
var Util = new Util();

/************************************************************************/
/* Main Pane                                                            */
/************************************************************************/

(function () {
    var MainPane = window.MainPane = function () {
        return new MainPane.fn.init();
    };
    MainPane.fn = {
        init : function () {
            this.errorPane = new ErrorPane();
            this.pane = $("#main-pane");
            
            
            
            this.chatMessagePane = new ChatMessagePane();
            this.friendListPane = new FriendListWindow();
            
            this.clientPanes = Array();
            this.clientPanes[0] = this.chatMessagePane;
            this.clientPanes[1] = this.friendListPane;
            
            for(var i = 0; i < this.clientPanes.length; i++) {
                this.clientPanes[i].pane.width(this.pane.width());
            }
            
            var lastPane = conf.lastPane;
            this.activatePane(this.clientPanes[lastPane]);
        },
        
        refresh: function() {
            this.activePane.display(true);
            for(var i = 0; i < this.clientPanes.length; i ++) {
                this.clientPanes[i].refresh();
            }

        },
        nextPane: function() {
            var nextPane;
            for(var i = 0; i < this.clientPanes.length; i++) {
                    if(this.activePane == this.clientPanes[i]) {
                     
                        if(i == this.clientPanes.length - 1) {
                            nextPane = this.clientPanes[0];
							System.Gadget.Settings.write("lastPane", 0);
                            break;
                        } else {
                            nextPane = this.clientPanes[i + 1];
							System.Gadget.Settings.write("lastPane", i + 1);
                        }
                    }
                    
            }
            
            // TODO: Cancel Animate
            while(this.activePane.pane.queue().length != 0) {
                
                this.activePane.pane.dequeue();
            }
            
            this.activePane.pane.animate({left: this.pane.width() + 1}, 500);
            nextPane.pane.css("left", -(this.pane.width()));
            nextPane.pane.animate({left: 0}, 500);
            this.activePane = nextPane;
        },
        prevPane: function() {
            var nextPane;
            for(var i = 0; i < this.clientPanes.length; i++) {
                if(this.activePane == this.clientPanes[i]) {
                    if(i == 0) {
                        nextPane = this.clientPanes[this.clientPanes.length - 1];
						System.Gadget.Settings.write("lastPane", this.clientPanes.length - 1);
                        break;
                    } else {
                        nextPane = this.clientPanes[i - 1];
						System.Gadget.Settings.write("lastPane", i - 1);
                        break;
                    }
                }
            }
            
            // TODO: Cancel Animate
            while(this.activePane.pane.queue().length != 0) {
                
                this.activePane.pane.dequeue();
            }
            
            this.activePane.pane.animate({left: -(this.pane.width())}, 500);
            nextPane.pane.css("left", this.pane.width());
            nextPane.pane.animate({left: 0}, 500);
            this.activePane = nextPane;
        
        },
        activatePane: function(pane) {
            for(i = 0; i < this.clientPanes.length; i++) {
                if(this.clientPanes[i] == pane) {
                    this.clientPanes[i].pane.css("left", 0);
                    System.Gadget.Settings.write("lastPane", i);
                } else {
                    var left = this.pane.width() + 1;
                    this.clientPanes[i].pane.css("left", left);
                }
                this.clientPanes[i].pane.css("display", "block");
            }
            this.activePane = pane;
            this.refresh();  
        },
        scrollUp: function() {
            this.activePane.scroll(this.pane.height() * 0.9);
        
        },
        scrollDown: function() {
            this.activePane.scroll(this.pane.height() * (-0.9));
        },
        height: function(height) {
            this.pane.Height(height);
        
        },
        width: function(width) {
            this.pane.Width(width);
        
        },
        onGadgetMouseLeave: function(e) {
            this.chatMessagePane.scrollToLastMessage();
        },
        systemMessage: function(msg) {
            this.chatMessagePane.appendSystemMessage(msg);
        },
        debugMessage: function(msg) {
            this.chatMessagePane.appendDebugMessage(msg);
        },
        error: function(msg) {
            this.errorPane.setMessage(msg);
            this.errorPane.display(true);
            for(var i = 0; i < this.clientPanes.length; i++) {
                this.clientPanes[i].display(false);
            }
        },
        hideError: function() {
            this.errorPane.display(false);
            for(i = 0; i < this.clientPanes.length; i++) {
                this.clientPanes[i].display(true);
            }
            this.activatePane(this.activePane);
        }
    }
    MainPane.fn.init.prototype = MainPane.fn;
}
)();

/************************************************************************/
/* Error Pane                                                            */
/************************************************************************/

(function () {
    var ErrorPane = window.ErrorPane = function () {
        return new ErrorPane.fn.init();
    };
    ErrorPane.fn = {
        init : function () {
            this.pane = $("#error-pane");
            this.refresh();
        },
        
        refresh: function() {

            this.pane.empty();
        },
        setMessage: function(msg) {
            var html = "<table style='height: 100%; width:100%;'><tr><td><div style='background:url(images/error.png) no-repeat; padding-left: 18px; text-align: left; font-weight: bold;'>" + msg + "</div></td></tr></table>";
            this.pane.html(html);
            
        },
        display: function(flg) {
            if(flg) {
                this.pane.css("display", "block");
            } else {
                this.pane.css("display", "none");
            }
        }
    }
    ErrorPane.fn.init.prototype = ErrorPane.fn;
}
)();

/************************************************************************/
/* Chat Message Pane                                                                     */
/************************************************************************/
(function () {
    var ChatMessagePane = window.ChatMessagePane = function () {
        return new ChatMessagePane.fn.init();
    };
    ChatMessagePane.fn = {
        init : function () {
            this.pane = $("#chat-message-pane");
            this.refresh();
        },
        
        refresh : function() {
          // font size
		  this.pane.children("div").css("font-size", conf.fontSize);
		  
		  // chat message
		  $(".chat-message").each(function() {
                
                if($(this).hasClass("chat-message-status-sending")) {
                    $(this).css("color", conf.colorMessageSending);
                }
                
                if($(this).hasClass("chat-message-status-sent")) {
                    $(this).css("color", conf.colorMessageSent);
                    
                }
                
                if($(this).hasClass("chat-message-status-received")) {
                    $(this).css("color", conf.colorMessageReceived);
                }
                
                if($(this).hasClass("chat-message-status-read")) {
                    $(this).css("color", conf.colorMessageRead);
                }
                
            });
            // System Message
			if(conf.showSystemMessage) {
				$(".system-message").css("display", "block");
			} else {
				$(".system-message").css("display", "none");
			}
			
			// Debug Message
            if(conf.showDebugInfo) {
                $(".debug-message").addClass("debug-message-visible");
                
            } else {
                $(".debug-message").removeClass("debug-message-visible");
            }
			
			// Scroll to Last Message
			this.scrollToLastMessage();
        },
        changeMessageStatus : function(message, status) {
            
            if((message.Type != TChatMessageType.cmeSaid) 
                & (message.Type != TChatMessageType.cmeEmoted)) {
                return;
            }
            
            var msgId = "chat-message-id-" + message.Id;
            var msgFrom = "<span class='chat-message-from'>" + Util.htmlEncode(message.FromDisplayName) + ":</span>";
            
           	// url
            var rurl = new RegExp("(((https|http|ftp)?:\\/([^\\s�?*))|(\\\\[^\\s�?*)|((skype|about):[^\\s�?*))","gi");
            rurl.global = true;
            var msgBody = Util.htmlEncode(message.Body);
            msgBody = msgBody.replace(rurl,
                '</span></a><a class="chat-link">$&</a><a><span class="chat-message-body">');
            msgBody = "<span class='chat-message-body'>" + msgBody + "</span>";
 
            // TODO: face icon replace 
            
            var msgHtml= "<div class='chat-message' id='" + msgId + "'><a class='chat-message-click-dummy'></a><a>" + msgFrom + msgBody + "</a></div>";
            $(msgHtml)
			
            // Append   message
			var flgAppend = false;
			var divMsg = $("#" + msgId);
            if(divMsg.length == 0) {
				flgAppend = true;
				// Append new message
                this.pane.append(msgHtml);
				divMsg = $("#" + msgId);
				
				// click event 
	            divMsg.click(function(e) {
					// check if clicked url or message
					var elem = $(document.elementFromPoint(e.pageX, e.pageY));
					if (elem.hasClass('chat-link')) {
						// Open url
						location.href = elem.text();
					} else {
						// Open chat window.
						try {
							message.Chat.OpenWindow();
						} 
						catch (e) {
						// Do Nothing.
						}
					}
	            });
	            
	            // hover event for highlight
	            divMsg.hover(function() {
	               divMsg.addClass("chat-message-highlight");
	            }, function() {
	               divMsg.removeClass("chat-message-highlight"); 
	            });
            }
            
            // add status class
            var fontColor;
            switch(status) {
            case -1: // Unknown
                divMsg.addClass("chat-message-status-unknown");
                fontColor = conf.colorMessageUnknown;
                break;
            case 0: // Sending
                divMsg.addClass("chat-message-status-sending");
                fontColor = conf.colorMessageSending;
                break;
            case 1: // Sent
                divMsg.addClass("chat-message-status-sent");
                fontColor = conf.colorMessageSent;
                break;
            case 2: // Received
                divMsg.addClass("chat-message-status-received");
                fontColor = conf.colorMessageReceived;
                break;
            case 3: // Read
                divMsg.addClass("chat-message-status-read");
                fontColor = conf.colorMessageRead;
                break;
            default:
                // Do Nothing
            }
            
            // Set Font Size & Color
            divMsg.css({ 
                "font-size": conf.fontSize,
                color: fontColor
            });
			if (flgAppend) {
				// autoscroll
				if (flgAutoScroll) {
					this.scrollToLastMessage();
				}
					            
				// delete old messages.
				this.deleteOldMessage();
			}
        },
        scrollToLastMessage: function() {
            if(!flgAutoScroll) return; 
            if(this.pane.height() <= $("#main-pane").height()) {
                this.pane.animate({top: 0}, 500);
            } else {
                var newTop =  $("#main-pane").height() - $("#chat-message-pane").height();
                this.pane.animate({top: newTop}, 500); 
            }
        
        },
        scroll: function(val) {
            var top = this.pane.css("top");
            var newTop = parseInt(top.replace("px","")) + val;
            if(val < 0) {
                var minTop = Math.min(0, $("#main-pane").height() - this.pane.height());
                newTop = Math.max(minTop, newTop);
            }
            if(val > 0) {
                newTop = Math.min(0, newTop);
            }
            this.pane.animate({top: newTop},500);
        },
        display: function(flg) {
            if(flg) {
                this.pane.css("display", "block");
            } else {
                this.pane.css("display", "none");
            }
        },
        appendDebugMessage: function(msg) {
            if(conf.debug) {
                debugMessageCount++;
                var msgId = 'debug-message-' + debugMessageCount;
                var msgHtml = "<div id='" + msgId + "' class='debug-message'>" + msg + "<div>";
                if(conf.showDebugInfo) {
                    $("#" + msgId).addClass("debug-message-visible");
                }
                this.pane.append(msgHtml);
				this.deleteOldMessage();
                if(flgAutoScroll) {
                	this.scrollToLastMessage();
            	}
            }
        },
        appendSystemMessage: function(msg) {
            var msgHtml = $("<div class='system-message'>" + msg + "<div>");
			msgHtml.css("font-size", conf.fontSize);
			if(conf.showSystemMessage) {
				msgHtml.css("display", "block");
			} else {
				msgHtml.css("display", "none");
			}
			
            this.pane.append(msgHtml);
			
			this.deleteOldMessage();
			if(flgAutoScroll)
				this.scrollToLastMessage();
        },
		deleteOldMessage: function() {
			if(this.pane.children().length > conf.maxMessage) {
				this.pane.children(":first").remove();
				this.deleteOldMessage();			
			} 
		}
        
    }
    ChatMessagePane.fn.init.prototype = ChatMessagePane.fn;
}
)();


/************************************************************************/
/* Friend List Pane                                                     */
/************************************************************************/


(function () {
    var FriendListWindow = window.FriendListWindow = function () {
        return new FriendListWindow.fn.init();
    };
    FriendListWindow.fn = {
        init : function () {
            
            this.pane = $("#friend-list-pane");
            this.refresh();
            
        },
        
        refresh : function() {
            try {
                var friends = Skype.Friends;
                this.pane.empty();
                for(var i = 1; i <= friends.Count; i++) {
                    var user = friends.Item(i);
                    this.changeOnlineStatus(user);    
                }
            } catch(e) {
                G_Error(MessageResource.ERROR.API_OPERATION_TIMEOUT);
            }
        },
        userToUserID : function(user) {
            return  'user-id-' + user.Handle;
        },
        userToOnlineStatusClassName: function(user) {
            switch(user.OnlineStatus) {
            case TOnlineStatus.olsUnknown : 
                return "user-online-status-unknown";
            case TOnlineStatus.olsOffline : 
                return "user-online-status-offline";
            case TOnlineStatus.olsOnline :
                return "user-online-status-online";
            case TOnlineStatus.olsAway :
                return "user-online-status-away";
            case TOnlineStatus.olsNotAvailable :
                return "user-online-status-not-available";
            case TOnlineStatus.olsDoNotDisturb :
                return "user-online-status-do-not-disturb";
            case TOnlineStatus.olsSkypeOut :
                return "user-online-status-skype-out";
            case TOnlineStatus.olsSkypeMe :
                return "user-online-status-skype-me";
            default:
                return "user-online-status-unknown";
            }
        },
        changeOnlineStatus : function(user) {
            // check if user is friend.
            var flgFriend = false;
            for(var i = 1; i <= Skype.Friends.Count; i++) {
                if(Skype.Friends.Item(i).Handle == user.Handle) {
                    flgFriend = true;
                    break;
                }
            }
            if(!flgFriend) return;
            
            var uid = this.userToUserID(user);
            var divUser = $("#" + uid);
            if(divUser.length == 0) {
                this.pane.append('<a id="' + this.userToUserID(user) + '"></a>');
            }
            
            divUser = $("#" + Util.jquerySelectorEscape(uid));
            divUser.attr("class", this.userToOnlineStatusClassName(user));
            divUser.attr("online-status", user.OnlineStatus);
            if(user.DisplayName.length > 0) {
                divUser.text(Util.htmlEncode(user.DisplayName));
            } else if(user.FullName.length > 0) {
                divUser.text(Util.htmlEncode(user.FullName));
            } else {
                divUser.text(Util.htmlEncode(user.Handle));
            }
            
            // click
            divUser.click(function(){
                try {
                    Skype.CreateChatWith(user.Handle).OpenWindow();
                } catch(e) {
                    G_Error(MessageResource.ERROR.API_OPERATION_TIMEOUT);
                }
            });
            
            // hover
            divUser.hover(
                function() {
                    divUser.addClass("user-hover");
                },
                function(){
                    divUser.removeClass("user-hover");
                }
            );
            
            // filter
            if(this.filter(user.OnlineStatus)) {
                divUser.css("display", "none");
            } else {
                divUser.css("display", "block");
            }
            
           
            G_Debug(user.Handle + ": status=" + user.OnlineStatus);
            
        },
        scroll: function(val) {
            var top = this.pane.css("top");
            var newTop = parseInt(top.replace("px","")) + val;
            if(val < 0) {
                var minTop = Math.min(0, $("#main-pane").height() - this.pane.height());
                newTop = Math.max(minTop, newTop);
            }
            if(val > 0) {
                newTop = Math.min(0, newTop);
            }
            this.pane.animate({top: newTop},500);
        },
        display: function(flg) {
            if(flg) {
                this.pane.css("display", "block");
            } else {
                this.pane.css("display", "none");
            }
        },
        filter: function(status) {
            if(conf.hideOfflineUser == true) {
                if(status == TOnlineStatus.olsOffline) return true;
            }
            
            return false;     
        }
        
    }
    FriendListWindow.fn.init.prototype = FriendListWindow.fn;
}
)();

/************************************************************************/
/* main                                                                 */
/************************************************************************/

System.Gadget.settingsUI = "settings.html";


$(document).ready(function(){
	G_LoadSettings();
	
    MP = new MainPane();
    
    System.Gadget.onSettingsClosed = G_OnSettingsClosed;
    
    
    $("#toolbar-button-up").click(function() {
        flgAutoScroll = false;
        MP.scrollUp();
    });
    $("#toolbar-button-down").click(function() {
        flgAutoScroll = false;
        MP.scrollDown();
    });
    $("#toolbar-button-back").click(function() {
        MP.prevPane();   
    });
    $("#toolbar-button-forward").click(function() {
        
        MP.nextPane();
    });
    
    $("body").bind("mouseenter", function() {
        if(flgAutoScroll == true) {
            flgAutoScroll = false;
        }
    });
    
    $("body").bind("mouseleave", function(e) {
        if(flgAutoScroll == false) {
            flgAutoScroll = true;
            
            MP.onGadgetMouseLeave(e);
        }
        flgDrag = false;
    });
    
    $("#resize-grab-pane").bind("mousedown",function(e){
        flgDrag = true;
        G_OnResize(e);
                
    });
    $("body").bind("mouseup",function(e){
        flgDrag = false;       
    });
    $("body").bind("mousemove", function(e) {
        if(flgDrag) {
            G_OnResize(e);
        }
    });
    if(Skype != null) {
        G_RegistEventHandler();
        G_AttachToSkype();
        G_OnAttachmentStatus(Skype.AttachmentStatus);
        MP.refresh();
    } else {
        G_Error(MessageResource.ERROR.API_NOT_INSTALLED);
    }
});

